//
// Created by Max on 2024/4/23.
//

#ifndef POLL_KEY_TV_THREAD_H
#define POLL_KEY_TV_THREAD_H

#include <pthread.h>
#include <unistd.h>
#include "hr_common.h"
#include "AnalysisFile.h"
#include "../MicLoader.h"

class TvThread;

class ITvThreadEvt {
public:
    virtual void OnTvMWThreadExit(TvThread *pTvMWThread) = 0;

    virtual ~ITvThreadEvt() {}
};

class TvThread {
public:
    using TvMWThreadFunc = void (*)(const void *arg);
    enum Flag {
        ONCE = 0x1 << 0,   /* just loop once */
        REPEAT = 0x1 << 1, /* repeat loop  */
        WAIT = 0x1 << 2,   /* wait for resume,only valid at first running */
    };
    using TvMWThreadFlag = enum Flag;

public:
    explicit TvThread(const TvMWThreadFunc func = nullptr,
                      const void *arg = nullptr, ITvThreadEvt *pEvt = nullptr);

    virtual ~TvThread();

    void Run(unsigned int flag = ONCE);

    void Suspend();

    void Resume();

    void Exit(); /* quit immediately */
    void ExitAndJoin();

protected:
    virtual void Run(const void *arg) {
        MI_UNUSED(arg);
    };

private:
    using TvMWThreadStat = struct {
        volatile bool wait; /* enable or disable TvMWThread */
        volatile bool once; /* select loop once or always */
        volatile bool exit; /* exit and recovery resource */
    };

    static void *Loop(void *arg);

    void Task();

private:
    TvMWThreadFunc mThreadFunc;
    const void *mArg;
    ITvThreadEvt *mEvt;
    pthread_t mId;
    TvMWThreadStat mStat;
    pthread_mutex_t mLock;
    pthread_cond_t mCond;
};

#endif //POLL_KEY_TV_THREAD_H
